package qc.module.platform.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.module.platform.dto.dbTable.DBTableDto;
import qc.module.platform.dto.dbTable.DBTableQueryConditionDto;
import qc.module.platform.entity.QcDbTable;
import qc.module.platform.entity.QcDbTableColumn;
import qc.module.platform.entity.QcDbTableSql;
import qc.module.platform.mapper.DBTableMapper;
import qc.module.platform.repository.QcDbTableColumnRepository;
import qc.module.platform.repository.QcDbTableRepository;
import qc.module.platform.repository.QcDbTableSqlRepository;

import java.util.List;
import java.util.Objects;

/**
 * DbTableService
 *
 * @author QuCheng Tech
 * @since 2024/1/29
 */
@Service
public class DbTableService {
    private QcDbTableRepository repository;
    
    @Autowired
    private QcDbTableSqlRepository sqlRepository;
    
    @Autowired
    private QcDbTableColumnRepository columnRepository;
    
    @Autowired
    private DbService dbService;

    @Autowired
    public void setRepository(QcDbTableRepository repository) {
        this.repository = repository;
    }

    /**
     * 查询数据库表信息，根据分类编码和关键字查询，均可以为空
     * @param conditionDto 查询条件对象
     * @return 数据库表信息集合
     * @author QuCheng
     * @since 2024/3/13
     */
    public List<DBTableDto> query(DBTableQueryConditionDto conditionDto){
        LambdaQueryWrapper<QcDbTable> wrapper = new LambdaQueryWrapper<>();
        if (Objects.nonNull(conditionDto)){
            if (StringUtils.isNotBlank(conditionDto.getCtgcode()))
                wrapper.eq(QcDbTable::getCtgcode,conditionDto.getCtgcode());

            if (StringUtils.isNotBlank(conditionDto.getKeywords())){
                //模糊匹配表名称和数据库编码
                wrapper.and(p -> {
                    p.like(QcDbTable::getCode,conditionDto.getKeywords()).or()
                            .like(QcDbTable::getName,conditionDto.getKeywords()).or()
                            .like(QcDbTable::getDb,conditionDto.getKeywords());
                });
            }
        }
        
        List<QcDbTable> ens = repository.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(ens)) return DBTableMapper.MAPPER.toDtoList(ens);
        return null;
    }

    /***
     * 获取指定表编码的表信息
     *
     * @param tableCode 表编码
     * @return qc.module.platform.dto.dbTable.DBTableDto
     * @author QuCheng Tech
     * @since 2024/2/1
     */
    public DBTableDto get(String tableCode) throws QCPromptException {
        if (StringUtils.isBlank(tableCode))
            throw new QCPromptException("查询数据库表信息时指定的数据库表代码不能为空");

        LambdaQueryWrapper<QcDbTable> wrapper = new LambdaQueryWrapper<>();

        wrapper.eq(QcDbTable::getCode, tableCode);

        QcDbTable en = repository.selectOne(wrapper);
        if (en != null)
            return DBTableMapper.MAPPER.toDto(en);

        return null;
    }

    /**
     * 新增
     * @param dto
     * @return 成功返回null，失败返回错误信息
     * @author QuCheng
     * @since 2024/3/13
     */
    public String add(DBTableDto dto){
        // 1.新增对象判空
        if (Objects.isNull(dto)) return QCUnifyReturnValue.Warn("对象不能为空");
        if (StringUtils.isBlank(dto.getCode())) return QCUnifyReturnValue.Warn("数据库表编码不能为空");
        if (StringUtils.isBlank(dto.getName())) return QCUnifyReturnValue.Warn("数据库表名称不能为空");
        if (StringUtils.isBlank(dto.getCtgcode())) return QCUnifyReturnValue.Warn("分类编码不能为空");
        if (StringUtils.isBlank(dto.getDb())) return QCUnifyReturnValue.Warn("数据库编码不能为空");
        
        // 2.判断数据表编码是否存在
        if(isExist(dto.getCode()))
            return QCUnifyReturnValue.Warn("数据库表编码已经存在");
        
        // 3.判断数据库编码是否存在，不存在则提示
        if (!dbService.isExist(dto.getDb())) return QCUnifyReturnValue.Warn("数据库编码不存在");
        
        // 4.dto转换为entity
        QcDbTable en = DBTableMapper.MAPPER.toEntity(dto);
        
        // 5.保存数据
        if (repository.insert(en) < 0x1)
            return QCUnifyReturnValue.Warn("新增数据失败");
        return QCUnifyReturnValue.Success();
    }

    /**
     * 修改
     * @param dto
     * @return 成功返回null，失败返回错误信息
     * @author QuCheng
     * @since 2024/3/13
     */
    public String update(DBTableDto dto){
        // 1.修改对象判空
        if (Objects.isNull(dto)) return QCUnifyReturnValue.Warn("对象不能为空");
        if (StringUtils.isBlank(dto.getCode())) return QCUnifyReturnValue.Warn("数据库表编码不能为空");
        if (StringUtils.isBlank(dto.getName())) return QCUnifyReturnValue.Warn("数据库表名称不能为空");
        if (StringUtils.isBlank(dto.getCtgcode())) return QCUnifyReturnValue.Warn("分类编码不能为空");
        if (StringUtils.isBlank(dto.getDb())) return QCUnifyReturnValue.Warn("数据库编码不能为空");

        // 2.判断修改的对象是否存在，不存在则提示
        if (!isExist(dto.getCode())) 
            return QCUnifyReturnValue.Warn("修改的数据库表信息不存在");
        
        // 3.判断数据库编码是否存在，不存在则提示
        if (!dbService.isExist(dto.getDb())) return QCUnifyReturnValue.Warn("数据库编码不存在");
        
        // 4.dto转换为entity
        QcDbTable en = DBTableMapper.MAPPER.toEntity(dto);
        
        // 5.修改数据
        repository.updateById(en);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 删除指定数据库表编码信息，同时删除数据库表sql信息和数据库表column信息。
     * @param tableCode 数据库表编码
     * @return 成功返回null，失败返回错误信息
     * @author QuCheng
     * @since 2024/3/13
     */
    public String delete(String tableCode) throws QCPromptException {
        // 1.条件判断
        if (StringUtils.isBlank(tableCode)) throw new QCPromptException("查询数据表信息时指定的数据表编码不能为空"); 
        
        // 2.根据数据表编码删除数据表sql信息
        LambdaQueryWrapper<QcDbTableSql> sqlWrapper = new LambdaQueryWrapper<>();
        sqlWrapper.eq(QcDbTableSql::getTbcode,tableCode);
        sqlRepository.delete(sqlWrapper);
        
        // 3.根据数据表编码删除数据表column信息
        LambdaQueryWrapper<QcDbTableColumn> columnWrapper = new LambdaQueryWrapper<>();
        columnWrapper.eq(QcDbTableColumn::getTbcode,tableCode);
        columnRepository.delete(columnWrapper);
        
        // 4.删除指定数据表信息
        repository.deleteById(tableCode);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 判断数据库表编码对象是否存在
     * @param tableCode 数据库表编码
     * @return 返回true表示存在，false表示不存在
     * @author QuCheng Tech
     * @since 2024/3/13
     */
    public boolean isExist(String tableCode){
        if (Objects.nonNull(repository.selectById(tableCode)))
            return true;
        return false;
    }
}
